// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


#ifndef CLOUDAPPENGINE_CAETCPCLIENTERRORTIMER_H
#define CLOUDAPPENGINE_CAETCPCLIENTERRORTIMER_H

#include <functional>
#include "../cae_common/CaeTimer.h"
#include "../cae_socket/CaeWebSocket.h"

using TimeoutHook = std::function<void (const string& clientIp)>;

class CaeTcpClientErrorTimer : public CaeTimer {
public:
    explicit CaeTcpClientErrorTimer(uint32_t interval, const string& connectionId);

    ~CaeTcpClientErrorTimer() override;

    void TimeoutCallback() override;

    void Restart();

    void Start();

    void Stop() noexcept;

    uint32_t GetDisconnectTimesMax() const;

    void SetTimeoutHook(const TimeoutHook &timeoutHook);

    void SetDisconnectHook(const TimeoutHook &disconnectHook);

    uint32_t m_disconnectTimes = 0;
    uint32_t m_start;
    string m_connectionId;

    TimeoutHook m_timeoutHook = nullptr;
    TimeoutHook m_disconnectHook = nullptr;
private:
    uint32_t m_disconnectTimesMax;
    pthread_mutex_t m_disconnectTimesLock;
};

class CaeTcpClientPauseTimer : public CaeTcpClientErrorTimer {
public:
    CaeTcpClientPauseTimer(uint32_t interval, uint32_t sec, const string& connectionId);

    ~CaeTcpClientPauseTimer() override;

    void TimeoutCallback() override;

private:
    uint32_t m_pauseTime;
};


class CaeNotouchTimer : public CaeTcpClientErrorTimer {
public:
    CaeNotouchTimer(const uint32_t interval, const uint32_t timeOut, const string& connectionId);

    ~CaeNotouchTimer() override;

    void TimeoutCallback() override;

private:
    uint32_t m_noTouchTime;
};


class CaeHandshakeTimeoutTimer : public CaeTcpClientErrorTimer {
public:
    CaeHandshakeTimeoutTimer(CaeWebSocket *ws, uint32_t interval, const string& connectionId);

    ~CaeHandshakeTimeoutTimer() override;

    void TimeoutCallback() override;

private:
    uint32_t m_handshakeTime;
    CaeWebSocket *m_webSocket;
};

/**
 * Trial Timer
 */
class CaeTrialTimeoutTimer : public CaeTcpClientErrorTimer {
public:
    explicit CaeTrialTimeoutTimer(const uint32_t maxTrialTime, const string& connectionId);

    ~CaeTrialTimeoutTimer() override;

    void TimeoutCallback() override;

private:
};

#endif // CLOUDAPPENGINE_CAETCPCLIENTERRORTIMER_H
